<?php

/***  DOCUMENTATION LAYER

Klenwell Array Sort Library

Last Update: Nov 2007
Author: Tom at klenwell@gmail.com

FUNCTIONS
array_sort_by_key($ASSOC_ARRAY, $sort_key, $primary_key, $order_by='ASC')

NOTES

______________________________________________________________________________*/


// array_sort_by_key
// sorts an associative array (of the type returned by mysql_fetch_assoc) on 
// specific key (i.e., col name).  Compare to php array_multisort function:
// http://www.php.net/manual/en/function.array-multisort.php
/*____________________________________________________________________________*/
function array_sort_by_key($ASSOC_ARRAY, $sort_key, $primary_key, $order_by='ASC') 
{
  $SORTED_ARRAY = array();     // return
  
  // validity arrays
  $VALID_ORDER_BY = array( 'ASC', 'DES' );
  
  // sanity check: order by value
  $order_by = strtoupper(substr($order_by,0,3));
  if ( !in_array($order_by, $VALID_ORDER_BY) )
  {
    trigger_error('invalid order_by value -- setting to ASC', E_USER_WARNING);
    $order_by = $VALID_ORDER_BY[0];
  }
  
  // sanity check: must be an array of associative arrays
  // derived from http://www.php.net/manual/en/function.is-array.php#73505
  $ONE_ROW = $ASSOC_ARRAY[0];
  if ( @array_merge($ONE_ROW) === $ONE_ROW && is_numeric( @implode( @array_keys( $ONE_ROW ) ) ) )
  {
    trigger_error('arrays (rows) in passed array are not associative -- this is the first row: ' . print_r($ONE_ROW,1), E_USER_ERROR);
    return false;
  }
  
  // sanity check: primary key exists
  if ( !isset($ONE_ROW[$primary_key]) )
  {
    trigger_error("primary key [$primary_key] not found in arrays to be sorted", E_USER_ERROR);
    return false;
  }
  
  // sanity check: sort key exists
  if ( !isset($ONE_ROW[$sort_key]) )
  {
    trigger_error("sort key [$sort_key] not found in arrays to be sorted", E_USER_ERROR);
    return false;
  }
  
  // still here?  then we're ready to sort
  // first, we get our sorting array
  foreach ( $ASSOC_ARRAY as $_ROW )
  {
    $_primary_key = $_ROW[$primary_key];
    $_SORTING[$_primary_key] = $_ROW[$sort_key];
  }
  
  // now we sort
  if ( $order_by == 'DES' )
  {
    arsort($_SORTING);
  }
  else
  {
    asort($_SORTING);
  }
  
  // map ARRAY back to SORTING array
  foreach ( $_SORTING as $_primary_key_val => $_sort_key_val )
  {
    // get index for ASSOC_ARRAY where ASSOC_ARRAY[][$primary_key] == $_primary_key_val
    foreach ($ASSOC_ARRAY as $_i => $_ROW)
    {
      if ( $_primary_key_val == $_ROW[$primary_key] )
      {
        $SORTED_ARRAY[] = $ASSOC_ARRAY[$_i];
        continue;
      }
    }
  }
  
	// return
	return $SORTED_ARRAY;
}
/*____________________________________________________________________________*/





// Testbed
/*____________________________________________________________________________*/

if ( 1 )
{
  print '<pre>';

  // test arrays
  $ARRAY = array
  (
    array( 'uid' => 1, 'last_name' => 'Klenwell', 'age' => 28 ),
    array( 'uid' => 2, 'last_name' => 'Gonzalez', 'age' => 38 ),
    array( 'uid' => 3, 'last_name' => 'Herrera', 'age' => 37 ),
    array( 'uid' => 4, 'last_name' => 'Audino', 'age' => 26 ),
    array( 'uid' => 5, 'last_name' => 'Zhang', 'age' => 30 ),
    array( 'uid' => 6, 'last_name' => 'Fick', 'age' => 35 ),
    array( 'uid' => 7, 'last_name' => 'Maruyama', 'age' => 35 ),
    array( 'uid' => 8, 'last_name' => 'Jameson', 'age' => 29 ),
    array( 'uid' => 9, 'last_name' => 'Waters', 'age' => 42 ),
    array( 'uid' => 10, 'last_name' => 'Guerrero', 'age' => 37 ),
  );
  $BAD_ARRAY1 = array
  (
    array( 'age', 25),
    array( 'age', 30),
    array( 'age', 35),
    array( 'age', 40)
  );
  
  // display our original array
  print "<br>ORIGINAL ARRAY\n";
  print_r($ARRAY);
  print '<hr>';

  // sort array ASC
  print "<h4>SORT ARRAY ON last_name ASC</h4>";
  $SORT1 = array_sort_by_key($ARRAY, $sort_key='last_name', $primary_key='uid', $order_by='ASC');
  print_r($SORT1);
  print '<hr>';
  
  // sort array DESC
  $ARRAY[] = array( 'uid' => 11, 'last_name' => 'Klenwell', 'age' => 28 );
  $ARRAY[] = array( 'uid' => 100, 'last_name' => 'Klenwell', 'age' => 15 );
  print "<h4>SORT ARRAY ON last_name DESC (w/ 2 additional Klenwells)</h4>";
  $SORT1b = array_sort_by_key($ARRAY, $sort_key='last_name', $primary_key='uid', $order_by='DESC');
  print_r($SORT1b);
  print '<hr>';
  
  // sort sorted array by age DESC
  print "<h4>SORT ARRAY ON age DESC</h4>";
  $SORT2 = array_sort_by_key($SORT1, $sort_key='age', $primary_key='uid', $order_by='DESC');
  print_r($SORT2);
  print '<hr>';
  
  // error tests
  print "<h4>Error Test: non-assoc array</h4>";
  $SORT3 = array_sort_by_key($BAD_ARRAY1, $sort_key='age', $primary_key='uid', $order_by='DESC');
  print_r($SORT3);
  print '<hr>';
  
  print '</pre>';
}

/*____________________________________________________________________________*/

?>
